﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using DataTransferObject;

namespace Engine.ScheduleAlgo
{
    class WrappedTaskCompareByDueDate : IComparable
    {
        // Class WrappedTaskCompareByDueDate này được tạo ra để sử dụng Decorator pattern cho class Task
        // Các đối tượng của class này sẽ bỏ vào PriorityQueue để lấy ra được task có duedate nhỏ nhất 
        public static int NOT_START = -1;

        #region Attributes

        private Task _task;
        private List<int> _predecessorIDs;
        private ArrayList _JList;
        private bool _isChosen;
        private bool _isScheduled;
        private double _startTime;
        public WrappedTaskCompareByDueDate(Task t, ArrayList JList)
        {
            _task = t;
            _predecessorIDs = _task.PredecessorIDs;
            _JList = JList;
            _isChosen = false;
            _isScheduled = false;
            _startTime = NOT_START;
        }

        // có nên chuyển MappedReleasDate và MappedDueDate lên class Decorator của Task hay ko?

        #endregion

        #region Properties
        public List<int> PredecessorIndices
        {
            get { return _predecessorIDs; }
            set { _predecessorIDs = value; }
        }
        public bool IsChosen
        {
            get { return _isChosen; }
            set { _isChosen = value; }
        }

        public bool IsScheduled
        {
            get { return _isScheduled; }
            set { _isScheduled = value; }
        }
        public Task Task
        {
            get { return _task; }
            set { _task = value; }
        }

        public int ProcessingTime
        {
            get { return Task.TotalWork; }
        }

        public double ReleaseTime
        {
            get
            {
                return _task.MappedReleaseDate;
            }
        }

        public double DueDate
        {
            get
            {
                return _task.MappedDueDate;
            }
        }
       

        public double Weight
        {
            get
            {
                return _task.Weight; ;
            }
        }

        public double StartTime
        {
            get 
            {
                if (!IsScheduled)
                {
                    return NOT_START;
                }
                else
                {
                    return _startTime;
                }
            }
            set 
            {
                if (IsScheduled)
                {
                    _startTime = value;
                }
                else
                {
                    // Task chưa được schedule thì không được set StartTime
                    _startTime = NOT_START;
                }
            }
        }
        #endregion



        #region IComparable Members

        int IComparable.CompareTo(object obj)
        {
            if (!(obj is WrappedTaskCompareByDueDate))
            {
                throw new InvalidOperationException("Compare with wrong object, not a WrappedTaskCompareByDueDate");
            }
            else
            {
                Task x = _task;
                Task y = (obj as WrappedTaskCompareByDueDate).Task;
                if (x.MappedDueDate > y.MappedDueDate)
                {
                    return -1;
                }
                else if (x.MappedDueDate < y.MappedDueDate)
                {
                    return 1;
                }
                else
                {
                    if (x.Equals(y))
                    {
                        return 0;
                    }
                    else
                    {
                        return -1;
                    }
                }
            }
        }

        #endregion

        #region Essential Methods

        public Boolean IsAvailableAt(double time)
        {
            foreach (int preTask in _predecessorIDs)
            {
                if (!(_JList[preTask] as WrappedTaskCompareByDueDate).IsScheduled)
                {
                    return false;
                }
            }
            if (IsChosen == true || _task.MappedReleaseDate > time)
            {
                return false;
            }
            return true;
        }
        #endregion
    }
}
